import requests
import json
from typing import Dict, Any, Optional, Callable
from config.api_config import BASE_URL, DEFAULT_HEADERS, REQUEST_TIMEOUT
from config.proxy_config import proxy_config
from websocket_client import websocket_client

class HttpClient:
    def __init__(self):
        self.base_url = BASE_URL
        self.headers = DEFAULT_HEADERS.copy()
        self.timeout = REQUEST_TIMEOUT
        self.session = requests.Session()
        self.session.headers.update(self.headers)
    
    def post(self, endpoint_path: str, data: Optional[Dict[str, Any]] = None, 
             custom_headers: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
        """发送POST请求"""
        url = f"{self.base_url}{endpoint_path}"
        headers = self.headers.copy()
        if custom_headers:
            headers.update(custom_headers)
        
        try:
            response = self.session.post(
                url, 
                json=data, 
                headers=headers, 
                timeout=self.timeout
            )
            return self._handle_response(response)
        except requests.exceptions.Timeout:
            raise Exception("请求超时")
        except requests.exceptions.ConnectionError:
            raise Exception("连接失败")
        except Exception as e:
            raise Exception(f"请求失败: {str(e)}")
    
    def get(self, endpoint_path: str, params: Optional[Dict[str, Any]] = None,
            custom_headers: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
        """发送GET请求"""
        url = f"{self.base_url}{endpoint_path}"
        headers = self.headers.copy()
        if custom_headers:
            headers.update(custom_headers)
        
        try:
            response = self.session.get(
                url, 
                params=params, 
                headers=headers, 
                timeout=self.timeout
            )
            return self._handle_response(response)
        except requests.exceptions.Timeout:
            raise Exception("请求超时")
        except requests.exceptions.ConnectionError:
            raise Exception("连接失败")
        except Exception as e:
            raise Exception(f"请求失败: {str(e)}")
    
    def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
        """处理响应"""
        if response.status_code == 200:
            content_type = response.headers.get('content-type', '')
            
            if 'application/json' in content_type:
                try:
                    return response.json()
                except json.JSONDecodeError:
                    raise Exception("响应不是有效的JSON格式")
            else:
                # 返回二进制数据
                return {
                    "type": "binary",
                    "data": response.content,
                    "content_type": content_type
                }
        else:
            raise Exception(f"HTTP错误 {response.status_code}: {response.text}")
    
    #登陆相关
    # 获取登陆二维码 MAC
    def get_qr_code_mac(self, device_id: str = "", device_name: str = "", login_type: str = "", proxy_name: str = "") -> Dict[str, Any]:
        proxy_settings = proxy_config.load_proxy_settings(proxy_name)
        request_body = {
            "DeviceID": device_id,
            "DeviceName": device_name,
            "Proxy": {
                "ProxyIp": proxy_settings.get("ProxyIp", ""),
                "ProxyPassword": proxy_settings.get("ProxyPassword", ""),
                "ProxyUser": proxy_settings.get("ProxyUser", "")
            }
        }
        return self.post("/api/Login/GetQRMac", request_body)
    
    # 获取登陆二维码 Car
    def get_qr_code_car(self, device_id: str = "", device_name: str = "", login_type: str = "", proxy_name: str = "") -> Dict[str, Any]:
        proxy_settings = proxy_config.load_proxy_settings(proxy_name)
        request_body = {
            "DeviceID": device_id,
            "DeviceName": device_name,
            "LoginType": login_type,
            "Proxy": {
                "ProxyIp": proxy_settings.get("ProxyIp", ""),
                "ProxyPassword": proxy_settings.get("ProxyPassword", ""),
                "ProxyUser": proxy_settings.get("ProxyUser", "")
            }
        }
        return self.post("/api/Login/LoginGetQRCar", request_body)
    
    # 检查二维码登录状态
    def check_qr_status(self, uuid: str, device_id: str) -> Dict[str, Any]:
        """
        Returns:
            Dict包含登录状态信息，格式为：
            {
                'Code': 0,  # 返回码，0表示成功
                'Success': True,  # 是否成功
                'Message': '登录成功',  # 消息
                'Data': {
                    'acctSectResp': {  # 登录成功时才有此字段
                        'userName': 'wxid_xxx',  # 用户名
                        'nickName': '昵称',  # 昵称
                        'alias': '微信号',  # 微信号
                        'bindMobile': '手机号',  # 绑定的手机号
                        'status': 102437,  # 状态码
                        # 其他字段...
                    }
                    # 其他字段...
                }
            }
        """
        body = {
            "Uuid": uuid,
            "deviceID": device_id
        }
        return self.post("/api/Login/CheckMacQR", body)
    
    # 心跳包检测账号状态
    def post_heartbeat(self, wxid: str) -> dict:
        return self.post("/api/Login/AutoHeartBeat?wxid=" + wxid)
    
    # 唤醒登录
    def wake_up_login(self, wxid: str, proxy_name: str = "") -> dict:
        proxy_data = {}
        if proxy_name:
            proxy_settings = proxy_config.get_proxy_by_name(proxy_name)
            if proxy_settings:
                proxy_data = {
                    "ProxyIp": proxy_settings.get("ProxyIp", ""),
                    "ProxyUser": proxy_settings.get("ProxyUser", ""),
                    "ProxyPassword": proxy_settings.get("ProxyPassword", "")
                }
        
        data = {
            "Wxid": wxid,
            "Proxy": proxy_data
        }
        return self.post("/api/Login/LoginAwaken", data)
    
    # 退出登录
    def logout(self, wxid: str) -> dict:
        return self.post("/api/Login/LogOut?wxid=" + wxid)
    
    # 好友相关
    # 搜索好友
    def search_friend(self, wxid: str, target: str) -> dict:
        request_body = {
            "FromScene": 0,
            "SearchScene": 0,
            "ToUserName": target,
            "Wxid": wxid
        }
        return self.post("/api/Friend/Search", request_body) 

    # 发送添加好友请求
    # Opcode: 2 添加好友
    # Scene: 3 微信号 15 手机号
    def request_friend(self, wxid: str, v1: str, v2: str, scene: int, verify_msg: str = "") -> dict:
        request_body = {
            "Opcode": 2,
            "Scene": scene,
            "V1": v1,
            "V2": v2,
            "VerifyContent": verify_msg,
            "Wxid": wxid
        }
        return self.post("/api/Friend/SendRequest", request_body)
    
    # 同意好友请求
    def pass_verify(self, wxid: str, v1: str, v2: str) -> dict:
        request_body = {
            "Scene": 0,
            "V1": v1,
            "V2": v2,
            "Wxid": wxid
        }
        return self.post("/api/Friend/PassVerify", request_body)

    # 消息相关
    # 同步消息
    def sync_message(self, wxid: str) -> dict:
        request_body = {
            "Scene": 0,
            "Synckey": "",
            "Wxid": wxid
        }
        return self.post("/api/Msg/Sync", request_body)
    
    # 发送文本
    def send_text_message(self, wxid: str, content: str, to_wxid: str) -> dict:
        request_body = {
            "At": "",
            "Content": content,
            "ToWxid": to_wxid,
            "Type": 1,
            "Wxid": wxid
        }
        return self.post("/api/Msg/SendTxt", request_body)
    
    # 发送语音
    def send_voice_message(self, wxid: str, base64: str, to_wxid: str, voice_time: int) -> dict:
        request_body = {
            "Base64": base64,
            "ToWxid": to_wxid,
            "Type": 2,  # AMR = 0, MP3 = 2, SILK = 4, SPEEX = 1, WAVE = 3
            "VoiceTime": voice_time,
            "Wxid": wxid
        }
        return self.post("/api/Msg/SendVoice", request_body)
    
    # 发送图片
    def send_image_message(self, wxid: str, base64: str, to_wxid: str) -> dict:
        request_body ={
            "Base64": base64,
            "ToWxid": to_wxid,
            "Wxid": wxid
        }
        return self.post("/api/Msg/UploadImg", request_body)
    
    # 发送链接
    def send_link_message(self, wxid: str, xml: str, to_wxid: str) -> dict:
        request_body = {
            "ToWxid": to_wxid,
            "Type": 0,
            "Wxid": wxid,
            "Xml": xml
        }
        return self.post("/api/Msg/ShareLink", request_body)
    
    # 群组相关
    # 同意加入群聊
    def consent_to_join_group(self, wxid: str, invite_url: str) -> dict:
        request_body = {
            "Wxid": wxid,
            "Url": invite_url
        }
        return self.post("/api/Group/ConsentToJoin", request_body)
    
    # 移动联系人到通讯录
    def move_contract_list(self, qid: str, wxid: str) -> dict:
        request_body = {
            "QID": qid,
            "Val": 3,
            "Wxid": wxid
        }
        return self.post("/api/Group/MoveContractList", request_body)
    
    # 邀请群成员 40人以上
    def invite_chat_room_member_upper_40(self, wxid: str, qid: str, member_wxid: str) -> dict:
        request_body = {
            "ChatRoomName": qid,
            "ToWxids": member_wxid,
            "Wxid": wxid
        }
        return self.post("/api/Group/InviteChatRoomMember", request_body)
    
    # 邀请群成员 40人以下
    def add_chat_room_member_lower_40(self, wxid: str, qid: str, member_wxid: str) -> dict:
        request_body = {
            "ChatRoomName": qid,
            "ToWxids": member_wxid,
            "Wxid": wxid
        }
        return self.post("/api/Group/AddChatRoomMember", request_body)
    
    # 扫码进群
    def scan_into_group_enterprise(self, wxid: str, url: str) -> dict:
        request_body = {
            "Url": url,
            "Wxid": wxid
        }
        return self.post("/api/Group/ScanIntoGroupEnterprise", request_body)
    
    # WebSocket相关方法
    def connect_websocket(self, user_name: str, message_callback: Callable = None, status_callback: Callable = None):
        """建立WebSocket连接"""
        return websocket_client.connect_user(user_name)
    
    def disconnect_websocket(self, user_name: str):
        """断开WebSocket连接"""
        return websocket_client.disconnect_user(user_name)
    
    def is_websocket_connected(self, user_name: str) -> bool:
        """检查WebSocket是否已连接"""
        return websocket_client.is_connected(user_name)
    
    def get_websocket_status(self, user_name: str) -> dict:
        """获取WebSocket连接状态"""
        return websocket_client.get_connection_status(user_name)
    
    def get_all_websocket_status(self) -> dict:
        """获取所有WebSocket连接状态"""
        return websocket_client.get_all_connection_status()
    
    def get_consent_queue_size(self) -> int:
        """获取同意进群队列大小"""
        return websocket_client.consent_queue.qsize()
    
    def start_consent_timer(self):
        """启动同意进群定时器"""
        try:
            websocket_client.start_consent_timer()
        except Exception as e:
            print(f"❌ 启动同意进群定时器时出错: {e}")
            
    def stop_consent_timer(self):
        """停止同意进群定时器"""
        try:
            websocket_client.stop_consent_timer()
        except Exception as e:
            print(f"❌ 停止同意进群定时器时出错: {e}")
    
    def reconnect_websocket(self, user_name: str):
        """重新连接WebSocket"""
        return websocket_client.reconnect_user(user_name)

# 全局HTTP客户端实例
http_client = HttpClient()